package com.edu.juc.lock;

/**
 * 悲观锁：认为自己在使用数据的时候一定有别的线程来修改数据，因此在获取数据的时候会先加锁，确保数据不会被别的线程修改。
 * synchronized 和 Lock 的实现类都是悲观锁
 * 乐观锁：认为自己使用的数据不会被别的线程修改，因此在获取数据的时候不会加锁。
 * 在Java中是通过使用无锁编程来实现，只是在更新数据的时候去判断，之前有没有别的线程更新了这个数据。
 * 最常使用的是CAS算法，Java原子类中的递增操作就通过CAS自旋来实现的。
 * <p>
 * 每个锁对象拥有一个锁计数器和一个指向持有该锁的线程的指针。
 * 当执行monitorenter时，如果目标对象的计数器为0，那么说明它没有被其他线程所持有，Java虚拟机会将该锁对象的持有线程设置为当前线程，
 * 并将其计数器加1.
 * 在目标锁对象的计数器不为0的情况下，如果锁对象的持有线程是当前线程，那么Java虚拟机会将计数器加1，
 * 否则Java虚拟机会阻塞当前线程，并等待锁对象被释放。
 * 当执行monitorexit时，Java虚拟机会将锁对象的计数器减1。
 * 计数器为0代表锁已被释放。
 *
 * jps -l : 获取进程ID
 * jstack ID : 获取进程的堆栈信息
 */
public class LockMain {
    public static void main(String[] args) {
        Object object = new Object();
        synchronized (object) {
            synchronized (object) {
                System.out.println(1 / 0);
                synchronized (object) {
                    System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
                }
            }
        }
    }

}
